<?php

namespace app\common\service;

use think\Controller;
use think\Config;
use app\common\service\OssService;
use app\common\service\MemberGetwayService;
use app\index\service\FaceRecognitionService as IndexFaceRecognitionService;
use app\common\common\FTP;  
use app\common\service\BaiduService;

/**
 * 百度人脸识别脚本的逻辑层
 *
 * @author jiang.ding
 */

class FaceRecognitionService{

    private $_ossServiceGrant;
    private $_ossServiceCamera;
    private $_ftp;
    private $_baiduService;
  
    /**
     *  1.实例化百度接口 2.实例化OSS接口 3.登录FTP账号
     */
    public function __construct() {
         
        # 创建FTP对象,创建百度人脸接口对象,创建OSS的bucket对象
        $this->_ftp = new FTP();
        $this->_baiduService = new BaiduService();
        $this->_ossServiceGrant = new OssService(Config::get('ALIYUN_OSS_FACE_GRANT_BUCKET'));
        $this->_ossServiceCamera = new OssService(Config::get('ALIYUN_OSS_FACE_CAMERA_BUCKET'));
              
    }

    /**
     * 先上传图片到OSS,再将图片存入member_face
     * @param $obj OSS的bucket对象
     * @param $url string 图片路径[图片路径中含'#',需要urlencode/urldecode转码]
     * @return $fileInfo array  [图片路径,图片路径]
     */
    public function ossUpload($obj,$url, $companyId = 1) {

        $url = urlencode(trim($url,'/'));
        $imgPath = trim(Config::get('BAIDU_FTP_CAMERA_PATH'),'/') . '/' . $url;    //拼接成文件全路径
        $fileName = pathinfo($imgPath);
        $picUrl = $companyId . '/' . date('YmdH') . '/' . $fileName['basename']; //阿里云路径
        $content = file_get_contents("{$imgPath}");
        $filePath = $obj->fileUpload($picUrl, $content);
        return [
            'pic_url' => pathinfo($picUrl)['dirname'] . '/' . urldecode(pathinfo($picUrl)['basename']),
            'file_path' => pathinfo($filePath)['dirname'] . '/' . urldecode(pathinfo($filePath)['basename']),
        ];
    }

    /**
     * 抓拍全部流程 
     * 1)上传图片到OSS, 2)人脸检测, 3)人脸识别(符合),添加到到店表 4)不存在,人脸注册
     * @param $companyId string   集团ID(宝岛)
     * @return $arriveRes object   到店会员信息结果集
     */
    public function addCameraPic($companyId) {  //宝岛定制版
       
        # FTP获取抓拍的图片地址(数组)
        $picPath = $this->_ftp->getCameraPic();   
        if (true === empty($picPath)) {
            echo '摄像机没有抓拍到图片(正常)' . "\n";
            echo date('Y-m-d H:i:s', time()) . "\n";
        }

        foreach ($picPath as $url) {
           
            # 上传到OSS
            $filePath = $this->ossUpload($this->_ossServiceCamera,$url); //$url中的'#'要urlencode:

            # 若OSS上传成功,则清空存放摄像机图片的FTP文件目录
            if ($filePath['pic_url'] === $filePath['file_path']) {

                //调用清空FTP的方法
                $fileName = pathinfo($filePath['pic_url'])['basename'];
                $this->_ftp->deleteCameraPic($fileName);
            } else {
                echo 'OSS上传失败' . "\n";
                echo date('Y-m-d H:i:s') . "\n";
            }

            # 获取带有签名的url
            $getSignData = [
                'bucket' => Config::get('ALIYUN_OSS_FACE_CAMERA_BUCKET'),
                'object' => $filePath['file_path'], 
            ];
            $picPath = $this->_ossServiceGrant->getSignUrl($getSignData);

            # 人脸检测
            $detectRes = $this->_baiduService->detect(['url' => $picPath]);
            $service = new IndexFaceRecognitionService($companyId);  
            
            #若检测结果不为空
            if (false === empty($detectRes['result'][0])) {

                $completeness = $detectRes['result'][0]['qualities']['completeness'];

                # 添加人脸注册图片记录(member_face)
                $faceData = [
                    'pic_url' => $filePath['file_path'],
                    'group_id' => Config::get('BAIDU_FACE_CAMERA_GROUP'),       
                    'come_from' => 'baidu',
                    'arrive_time' => date('Y-m-d H:i:s', time()),
                ];

                $addFaceData = array_merge($faceData, $detectRes['result'][0]);
                $memberFaceRes = $service->addMemberFace($addFaceData);

                # 判断人脸是否符合要求(完整度)
                if ((int) $completeness === 1) {

                    # 若符合要求,且不为店员,则进行人脸识别
                    $identifyRes = $this->_baiduService->identifyUser(['url' => "{$picPath}", 'groupId' => Config::get('BAIDU_FACE_GRANT_GROUP')]);    //查询会员授权人脸分组
                    $identifyUid = explode('_',$identifyRes['result'][0]['uid']);
                   
                    # 取右边第一个横杠,作为分割符,并查询获取设备所属的门店ID
                    $pos = strrpos(pathinfo($filePath['pic_url'])['basename'],'-');
                    $sodSnName = substr(pathinfo($filePath['pic_url'])['basename'],0,$pos);
                    $sodSnNameArr = explode('#',$sodSnName);
                    $getStoreIdWhere['companyId'] = $sodSnNameArr[0];
                    $getStoreIdWhere['sodSnName'] = $sodSnNameArr[2];
                    $storeId = $service->getStoreIdBySodSnName($getStoreIdWhere)['store_id'];
                    
                    # 若为店员,则不添加到店(人脸和授权图片一一对应)
                    $grantInfo = $service->getMemberGrantInfo(['member_code'=>$identifyUid[0],'grant_id'=>$identifyUid[1]]);
                    if ((int)$grantInfo->is_staff === 1) {
                        
                        echo '当前到店会员为门店工作人员';
                        echo date("Y-m-d H:i:s");
                    } else {
                        
                        # 授权分组中是否存在相同图片
                        if ($identifyRes['result'][0]['scores'][0] >= 80) {

                            # 若存在,则查重,避免重复添加(同一会员同一天可在多个门店到店)
//                            $arriveInfo = $service->getMemberArriveInfo(['member_code'=>$identifyUid[0],'store_id'=>$storeIdArr[0]]);
                            $arriveInfo = $service->getMemberArriveInfo(['member_code'=>$identifyUid[0],'store_id'=>$storeId]);

                            # 修改member_face(补上member_code字段)
                            $updateMemberFace = $service->updateMemberFace(['member_code' => $identifyUid[0]], ['id' => $memberFaceRes->id]);

                            if (true === empty($arriveInfo)) {
                                # 若不重复,则将信息添加到arrive到店表中
                                $arriveData = [
                                    'member_code' => $identifyUid[0],
                                    'store_id' => $storeId,
                                    'grant_id' => (int)$identifyUid[1],
                                    'create_time' => date('Y-m-d H:i:s', time()),
                                ];
                                $arriveRes = $service->addMemberArrivePic($arriveData);

                            } else {
                                echo '该用户已经到店' . "\n";
                                echo date('Y-m-d H:i:s') . "\n";
                            }
                        } else {

                            # 思路: 用户图片不存在, 添加潜客信息，并注册抓拍图片到抓拍人脸分组
                            ## 先人脸识别,防止重复注册潜客,(且一个潜客对应一张人脸)
                            $identifyCameraRes = $this->_baiduService->identifyUser(['url' => "{$picPath}", 'groupId' => Config::get('BAIDU_FACE_CAMERA_GROUP')]);
                           
                            if ($identifyCameraRes['result'][0]['scores'][0] < 80) {

                                ## 添加潜客记录,
                                $addIndexData = [
                                    'come_from' => 7,
                                    //'gender' => $addFaceData['gender'], //不准
                                    'add_ts' => time(),
                                    'last_ts' => time(),
                                    'jj_uni_id' => uniqid(),
                                    'wx_union_id' => '',
                                    'orther_user_id' => '',
                                    'old_name' => '',
                                    'old_gender' => '',
                                    'old_birthday' => '',
                                    'old_mobile' => '',
                                    'old_account_code' => '',
                                ];
                                $memberIndexRes = $service->addMemberIndex($addIndexData);

                                ## 修改member_face(补上member_code字段)
                                $updateMemberFace = $service->updateMemberFace(['member_code' => $memberIndexRes->member_code], ['id' => $memberFaceRes->id]);

                                ## 在抓拍分组中进行人脸注册(分组:camera_group),uid=member_code拼接face_id
//                                $uid = $memberIndexRes->member_code . '_' . $memberFaceRes->id;
//                                $userInfo = Config::get('BAIDU_FACE_CAMERA_USER_INFO');
//                                $groupId = Config::get('BAIDU_FACE_CAMERA_GROUP');   //第一次到店的人脸分组
//                                $baiduImg = file_get_contents($picPath);
//                                $addBaiduDbRes = $this->_baiduAip->addUser($uid, $userInfo, $groupId, $baiduImg);
                                $addBaiduData = [
                                    'url' => $picPath,
                                    'uid' => $memberIndexRes->member_code . '_' . $memberFaceRes->id,
                                    'userInfo' => Config::get('BAIDU_FACE_CAMERA_USER_INFO'),
                                    'groupId' => Config::get('BAIDU_FACE_CAMERA_GROUP'),     //第一次到店的人脸分组
                                ];
                                $addBaiduDbRes = $this->_baiduService->addBaiduFace($addBaiduData);

                                ## 若存在错误码,则返回百度错误信息
                                if ($addBaiduDbRes['error_code']) {
                                    echo '百度人脸错误码: ' . $addBaiduDbRes['error_code'] . "\n";
                                    echo '百度人脸错误信息: ' . $addBaiduDbRes['error_msg'] . "\n";
                                    echo date('Y-m-d H:i:s', time()) . "\n";
                                }
                            } else {
                                
                                $identifyCameraUid = explode('_',$identifyCameraRes['result'][0]['uid']);
                                
                                 ## 修改member_face(补上member_code字段)
                                $updateMemberFace = $service->updateMemberFace(['member_code' =>  $identifyCameraUid[0]], ['id' => $memberFaceRes->id]);
                                echo '该用户已存在抓拍分组中: ' . "\n";
                                echo date('Y-m-d H:i:s', time()) . "\n";
                            }
                        }
                    }
                    
                } else {
                    
                    echo '人脸不够完整: ' . "\n";
                    echo date('Y-m-d H:i:s', time()) . "\n";
                }
            } else {

                echo '未检测到人脸: ' . "\n";
                echo date('Y-m-d H:i:s', time()) . "\n";
            }
        }
    }

}

